% sgems_write : write sgems binary data structure
%
% Call:
%   O=sgems_write(filename,O)
%
%   O: sgems data structure
%   filename : filename
%
% See also: sgems_read, sgems_write_pointset, sgems_write_grid
%
function O=sgems_write(filename,O)

if nargin<2
    help mfilename
    O=[];
    return
end

MN       = 1.561792946e+9;
fidSgems = fopen(filename,'w');
if fidSgems<1
    mgstat_verbose(sprintf('%s : could not open %s for writing',mfilename,filename),10);
    O=[];
    return
end


% READ MAGIC NUMBER
if ~isfield(O,'magic_number');O.magic_number=1.561792946e+9;end


fwrite(fidSgems,O.magic_number,'uint32');

% TYPE DEFINITION
if ~isfield(O,'type_def');
    if isfield(O,'nx');
        O.type_def='Cgrid';
    else
        O.type_def='Point_set';
    end
end
% if (strcmp(O.type_def,'Point_set')|strcmp(O.type_def,'Cgrid'));
%     mgstat_verbose(sprintf('%s : Using type definition ''%s''',mfilename,O.type_def),1)   
% else
%     mgstat_verbose(sprintf('%s : unsupported type definition (%d)',mfilename,O.type_def),10)
%     return
% end


if ~isfield(O,'version')
    O.version=100;
end
n_prop=size(O.data,2);
if ~isfield(O,'n_prop')
    O.n_prop=size(O.data,2);
end
if (n_prop)~=(O.n_prop),
    O.n_prop=n_prop;
    mgstat_verbose(sprintf('%s : adjusting n_prop=%d',mfilename,n_prop),10);
end


% TYPE DEF
fwrite_charstar(fidSgems,O.type_def)

% IF POINT SET
if strcmp(O.type_def,'Point_set');
    mgstat_verbose(sprintf('%s : Writing POINTSET data to %s',mfilename,filename),1)

    % POINT SET NAME
    fwrite_charstar(fidSgems,O.point_set)

    % VERSION
    fwrite(fidSgems,O.version,'int32','b');
    if (O.version<100)
        mgstat_verbose(sprintf('%s : file too old (%s)',mfilename,file))
        return
    end

    % SIZE
    n_data=size(O.data,1);
    if ~isfield(O,'n_data'); O.n_data=n_data;end
    if (n_data)~=(O.n_data),
        O.n_data=n_data;
        mgstat_verbose(sprintf('%s : adjusting n_data=%d',mfilename,n_data),10);
    end

    fwrite(fidSgems,O.n_data,'uint32','b');
    fwrite(fidSgems,O.n_prop,'uint32','b');

    for i=1:O.n_prop
                
        
        if ischar(O.property_name)
            str=O.property_name;
            O=rmfield(O,'property_name');
            O.property_name{i}=str;
        end
        
        try
            property_name=O.property_name{i};
        catch
            property_name=sprintf('D%d',i);
            try;O.property_name{i}=property_name;end
        end
        fwrite_charstar(fidSgems,property_name);
        
    end

  
    % PADD ZEROS FOR MISSING DIMS
    if size(O.xyz,2)==1; O.xyz(:,2:3)=0;end
    if size(O.xyz,2)==2; O.xyz(:,3)=0;end
    %d=O.xyz';
    fwrite(fidSgems,transpose(O.xyz),'float32','b');
    %% old and slower:
    %for j=1:O.n_data
    %    fwrite(fid,O.xyz(j,:),'float32','b');
    %end
  
    fwrite(fidSgems,O.data(:),'float32','b');
    %% old and slower
    %for k=1:O.n_prop
    %    fwrite(fid,O.data(:,k),'float32','b');
    %end
    
elseif strcmp(O.type_def,'Cgrid');
    disp(sprintf('%s : Writing CARTESIAN GRID (Cgrid) to %s',mfilename,filename))
    
    % POINT SET NAME
    fwrite_charstar(fidSgems,O.grid_name);
    
    % VERSION
    fwrite(fidSgems,O.version,'int32','b');

    % SIZE
    fwrite(fidSgems,[O.nx O.ny O.nz],'uint32','b');
    fwrite(fidSgems,[O.xsize O.ysize O.zsize],'float32','b');
    fwrite(fidSgems,[O.x0 O.y0 O.z0],'float32','b');

    % Properties
    fwrite(fidSgems,O.n_prop,'uint32','b');
    for i=1:O.n_prop
        fwrite_charstar(fidSgems,O.property{i});
    end

    % Data
    for i=1:O.n_prop
        fwrite(fidSgems,O.data(:,i),'float32','b');
    end

    
end

fclose(fidSgems);



function fwrite_charstar(fid,str);
    str_len=length(str)+1;
    str_len = fwrite(fid,str_len,'uint32','b');
    fwrite(fid,str,'char');
    fwrite(fid,0,'char');

